- web6047 - (2021/09/10(金) 現在、システム調整中のため、一部の表示がおかしいかもしれません)


[横幅 1024px以下]

web6047 2022年

プログラミングやRPG(作るほう)が好きな人の日記

個人的な趣味(プログラミング、イラスト、電子回路)のページです。

自身のパソコンのやりすぎに対する管理の表の公開、

最近見ているアニメや映画と 買い物の簡易なリスト、

それから日記を掲載しています。日記が主体です。

このWeb ページの構造について

ページが少しごちゃごちゃとしているため、このページの全体像をここに示します。

日記へ飛ぶにはここをクリックしてください

パソコン使用時間管理の公開:   パソコン使用時間管理

この表は、このウェブページの管理人のパソコンの使用時間を管理・制限するためのものです。

このようなプライベートなことを公開して、ちょっと恥ずかしいようなところもありますが、公開することでうまくいっているので良しとしています。





































NO PC WEEK に代わる PC 使用制限のしくみ(新β2版)
No.
(ID)
A1.
開始時
運動
A2.
勉 強
1問
A3.
終了時
運動
H1. 予定
作業内容
H2. 予定
作業詳細
判定×の理由
B. 実際
開始時刻
C. 予定
使用時間
(当日限度)
D. 予定
終了時刻
E. 実際
終了時刻
F. 実際
使用時間
G1. 判定
◎ 9分以下
○ 10分~19分
△ 20分~29分
× 30分以上
ちょっとこの表の更新を停止します。
でもパソコンの起動時間は自動的に記録されているので、1日当たりどのくらいパソコンを使っていたのかは、
データから起こすことが可能です。
今は表が無くても、電源制御により、おおむね、1.5h区切りで作業できているし、夜11:00には終了できているので、大丈夫かなと思っています。
0438









15分以上別のこと: 夕食
0909




17:46 1:40
19:26 1:40

※この表の自動化の話をここに書きましたが、自動化をするヒマがないので、もともとのやり方で再開します。

(こういう管理が自分の頭の外にないと まともにやれないなんて、「松葉づえ」を手放せずに生きているようなものだな…)

ちょっと面白いことを書きますが、パソコンを起動して、1:30時間が経つと、自動的に「ラジオ体操第一」の動画がフルスクリーンで表示され、その動画が終わると、パソコンはシャットダウンされるように、システムを調整してあります。笑い話ではないんですが、それほど、PC作業にとって身体の運動は、必須なんです。

また、夜23時から、翌日正午までの間にパソコンが起動されると、自動的にシャットダウンされるようにもなっています。「夜更かししないこと」は世間でも良く知られている健康の条件です。そして、「午前中に PC 作業しないこと」というのは、私が最近知った新しい健康の秘訣です。それが良いな、具合が良いなと実際に思ったんです。

この表の意図:

多くの人はパソコンのやりすぎやネットゲームのやりすぎには困っていると 思います。

参考に言うと、この表を使う前の私は 1 回の PC 使用時間がノンストップで 17 時間というときもあったし、平均で言うと毎日 9 時間はやっていたと思います。

この表を使ってパソコンの使用時間を 事前に決めてネッ ト上に公開 することで、パソコンのやりすぎを防止できたら、と思います。

また、数年前から考えてきましたが、そういう徹夜とか長時間作業をするよ りも、昼間の短時間作業のほうが生産性は高いのではないかと思います。そういう意味でも期待しています。

※以前は NO PC WEEK と称してパソコンを使用しない期間を設けることでやりすぎに対処してきましたが、もっと具合の良い方法はないかと考え、この表を使うようになりました。


臨時お試し(2022年1月8日~)

最近、状況が以下のように少し変化していて…

  • 23時で電源が切れる自動制御がとても強制的で、うまくいっている。
  • 23時以降まったくできなくなり、使用時間が減ってしまった。
  • 最近、通常のPC作業の他に、「PC-9801でのアセンブラ学習」が加わったので、さらに時間が足らなくなった。

…これまでのやり方だとうまくいかないところがあるので、お試しでやり方を少し変更します。

お試しで以下のようにします。

  • 基本的に何時間でもやってよい。
  • ただし、1.5h(または2.0h)ごとに区切り、区切りの際に15分以上 別のことを行う。
    行った内容は、参考のために記録と記録の間に記載する。
  • 使用可能時刻は、昼12:00~夜23:00のあいだ。(自動的に電源制御される)
  • 1.5hの開始時と終了時にこれまでどおり、開始時:運動、勉強、終了時:運動 を行うこと。
  • 以上は平日は火木金のみとし、月水は以下のようにする。
    月水は、「PC-9801でのアセンブラ学習」について基本的に本だけで学習する。
    しかし、必要な場合は1項目に限ってPC-9801の電源を入れて良い。

これがうまくいかない場合は、以上を取り消しします。

(「1.5h(または2.0h)ごとに区切り、」というのが難しいんじゃないかと思う…)

中途結果

  • これまでは 1.5h や 3, 4h の時間制限があったが、このお試しは時間が限られていないので、少し気持ちが楽になって良い。「余計なことで時間を使ってしまった~」というのが無い。


記入の規則:

  • 日付は表示していません(私の生活パターンをすべて知らせるのはよくないから)。しかし、白と灰色の色分けは、同じ色の連続 で同じ日を表しています。
  • 左端の「A1. 運動」、「A2. 1問」、「A3. 運動」について
    この表の目的とは異なりますが、ついでとして、遊び100%の毎日を送るときでも勉強の習慣を忘れないために、たった1問で良い ので解くことにします。
    正直言うと毎回遊ぶ前に必ず1問勉強するのは心が折れそうです。でも慣れさえすれば…と思います。(追記:やってみると結構効果 的で役立っています)
    行ったら◎、行わなかったら× を記入します。
    2020年11月20日ぐらいから「A1. 運動」を追加しました。パソコンを行う前に運動することを強制するものです。腕立て伏せ10回とか腹筋10回とかです。
    (ホントだったら30回くらいはやりたいところですが、私は体の調子が悪いので、10回程度にしています)
    2021年6月26日「A3. 運動」を追加。PC使用の終了時にも運動する。
    A1はPC漬けによる筋力衰え対策の意味で、筋トレを行い、
    A3はPC作業でこった体をほぐす意味で、ラジオ体操やストレッチ体操を行う。
  • 右端の「G. 判定」について
    「D. 予定終了時刻」と「E. 実際終了時刻」を比べて、オーバーした時間によって判定を行います。
    ◎ 9分以下
    ○ 10分~19分
    △ 20分~29分
    × 30分以上 (オーバー理由を記載する。理由の統計を取れば何が問題なのか把握でき、改善しやすいです)
  • 平日の 1.5h、2.0h の PC 使用の連続が負担になっているので、週のスケジュールは下記のようにする。
    月水で PC 使用しないことでうまいぐあいに「体力回復」されて、「生活」がうまく回り、プログラミング以外の「創作活動」(イラスト等)に時間が取れることを期待します。
    月:0h
    火:1.5h
    水:0h
    木:1.5h
    金:1.5h
    土:5hまで(休日で、翌日も休日)
    日:3hまで(休日で、翌日平日) ←早起きなおかつ(日々の買い物とかじゃなく)散歩するなら 3h やって良い
    (※2021年2月2日:週の各時間を調整しました)
    (※2021年12月12日:電源タイマーで23時で終了することに期待できるので土日の各時間を1時間ずつ増やしました)
  • ×、△、"記録しなかった長時間作業" が多いと思ったら、バランスをとるために、NO PC WEEK※ を1週間実施する。
    NO PC WEEK とは私自身の健康のために私のパソコンの使用を制限する期間です)


ちなみに、分単位で記録を取ったりして、だいぶマメに見えるかもしれませんが、Windows の日本語入力(MS-IME)で「いま」と入力し、 変換 キーを押さずに ボタンを押すと現在の時刻になります。道具の便利さが人をマメに見せるのかもしれません。

例外事項:

  • 「E. 実際終了時刻」のあと、プログラミングの場合のみスッパリ終了しないで、今後のプログラミングの方針をテキストファイルに書くのは OK にしています。


「スーパーPC WEEK」:

連休中(3連休以上)に、NO PC WEEK をオフにして好きなだけパソコンを使ってよいとする期間を、「NO PC WEEK」に対して「スーパーPC WEEK」と言う。

ただし以下の決まりを守ること。

  • その日に自由にパソコンを使ってもよいが、1回あたり、いつものように表に記入すること。(開始時運動、勉強1問、終了時運 動も行うこと)
     
  • 1回ごとに、掃除、炊事、洗濯や、別の趣味など、まとまった作業を はさむこと。
     (理由: 1回1回がが連続してつながると回を分けている意味がなくなるから)
  • 24時に就寝するよう努めること。(強制ではないが、つとめること)
     
  • 連休の最終日は通常通りとする。
     
  • 1回の使用時間は2時間を最大とすること。

なお、表の中央やや右寄りの「C. 予定 使用時間(当日限度)」列の "当日限度" には UNLOCK と記入する。


中途結果(2022/4):

(この記事は作成途中です)

現在固まってきた運用の内容をここにまとめます。

個人的ではありますが、自分にとって効果があると思っているものです。

ご参考になれば幸いです。

効果 大:

昼12時に電源供給が開始、夜11時に電源供給が終了するしくみ

電源オンオフタイマーを使用して、パソコンの電源タップへの電力の供給を制御します。

これにより、時間になるとマルチディスプレイの外付けの大きなディスプレイの電源が切れたり、オンされたりします。


パソコンの電源を入れた後、1.5Hで電源が切れる(休止状態になる)しくみ

1.5Hと1.5Hのあいだは15分以上別のことを行うルール

効果 中:

パソコン使用の前後に運動をする。

その他 続けていること:

パソコン使用の前に勉強の問題を1問解く

自分の家族にすすめたい方へ:


(これは イラス トAC の無料素材です)

パソコンのやりすぎやネットゲームのやりすぎは社会問題にもなっているので、「うちの子についてなんとかしないと…」と思っている ご家族の方は多くいらっしゃると思います。

私の両親も過去に私について問題にしていました。学校へ行かず、毎日朝までパソコンに向かい、 悶々としていたんです。


この表はその家族が困っていたときから 30 年後に、私が自分で必要を感じて作ったものです。

私は今 一人暮らしをしていて、自分で生計を立てる中、パソコンにおぼれた生活をすると、生活がうまく回らなくなるんです。

具体的には、

  • 人前で疲れた顔を見せてしまい、人間関係がうまくいかなくなる。もっと具体的には、職場、とこや、お店のレジ、歯医者。
  • 掃除、洗濯、炊事が後回しになり、実質、それらを行う時間がなくなってしまう。深夜遅くや翌日に回したり、行わなかったりす る。

これらを改善するために表を作りました。


でも、このような必要にせまられて「自分の動機で始めた場合」と、「人からすすめられて始めた場合」とでは、結果が異なると思いま す。

自分の切実な動機で始めたなら自分から進んでこの表を活用すると思いますが、外から押し付けられたものはなかなか定着しないもので す。

あまり適当なことは言えませんが、「中途結果」タブの中の青い部分で 書いたことは、本人にとって得になることなので、「ときどき休憩して、他のあの趣味やってみたらどうだ?」とか「ときどき休憩したほ うがプログラミングの質が上がるって話だぞ?」という形ですすめてみたらどうでしょうか。(それでも最終的には自立してもらうことは 必要だと思いますが)


私が両親を困らせていたときに、突然、外へ一人で出て行って、一人暮らしを始めたり、接客業を始めたり、いくつか資格取得したりと いろいろ行えた理由というのは、正直言ってわかりません。(※しかし途中で失業して2度、実家に戻ったことがあります。1 回目は 21 才くらいのときに 5 年間、2 回目は 35 才くらいのときに1年未満、実家にいて、何もしてなかったり働いたりしていました)

私が両親を困らせていたのは 16 才 ~ 20 才くらいの学生のころですが、そのころ家族と私自身と友人たちがみんなそれぞれ、私の生活について心配したり困ったり悩んだり、あの手この手を試したりしていました。そう いう煮詰まったような状況が運命をそのように(解決の方向へ)動かすのかもしれません。運命がどうの というのは変ですが、そのくらいのことしか言えません。何かしら取り組む必要があるということですかね。


この社会問題はクリアーすべきものみたいです。



最近観ているアニメ: 最近観ているアニメ
日 付
(上ほど新しい)
タイトル 無料配信
配信日
公評価 私 評価
2022/6/2~視聴中 デスノート(リンクはYahoo GYAO で検索)
サスペンス/2003年週刊少年ジャンプ/全37話
昔、「最近の週刊少年ジャンプはどうなのか」と、突然ジャンプを一冊買い、そのときたまたま同漫画の1話目を読みました。その後 数年後に友達に勧められて、面白くて単行本を全部買いました。
映画のほうも面白かったです。
2022年になって、同様に「最近のジャンプはどうなのか」と思って、手に取ってみてみると、なんか少女漫画みたいなのが2、3入っていて、少しびっくりしました。
聖闘士星矢今こそはばたけとか、お前はもう死んでいるとか、ボールは友達だとか、へのつっぱりはいらんですよ、とかそういう世界ではなくなっていた…。
毎日 4.7 4.4
2021/7/15~視聴中 ドラゴンボール改(リンクは Yahoo GYAO で検索)
冒険・格闘技/1984年週刊少年ジャンプ/各話25分程度
・・・・金土日 4.8 4.5
最近観た映画: 最近観た映画

このところ、Yahooの無料映画サービス「GYAO」で映画をいっぱい観ています。

映画の場合は公私それぞれ★ 3.5 以上で黄色塗りにします。★2.9以下は青塗りにします。

■■であれば公私ともに落第点。であれば公私で意見が分かれている。■■であれば公私ともにGOOD。白塗りは可もなく不可もなく。

日 付
(上ほど新しい)
タイトル 無料配信
(日付まで)
公評価 私 評価
2022/6 パッション(R15+)(リンクはGYAOで検索)
私のレビュータイトル:こういう映画もある。
まぁ、最初は、不思議な音楽とともに始まって、異色の映画を におわせている。
その通りで、この映画は途中からグラッとくる。
そのグラッと来たところも、まぁ、観ていられなくもない、、
グラッと来て、立ち直るのかどうかは観てのお楽しみかな。
サスペンス映画で、ノオミ・ラパス主演。
高めの評価になっていますが、同性愛と、ネガティブな内容で、その辺が苦手に思う人には合わないかも。
オススメ度:映画好きの人にオススメ
7月4日(月) 23:59まで 3.6 3.6

最近買ったもの: 最近買ったもの

買い物も映画と同じく、公私それぞれ★ 3.5 以上で黄色塗りにします。★2.9以下は青塗りにします。 ■■であれば公私ともに落第点。であれば公私で意見が分かれている。■■であれば公私ともにGOOD。白塗りは可もなく不可もなく。

日 付
(上ほど新しい)
タイトル 公評価 私 評価
2022/6/20 水戸駅ビルの書店へぶらりと立ち寄り、「アセンブラ独習」という4cmくらいの厚さの分厚い本を買おうかと思ったけど、身体に悪そうだと思い、ためらっていたところ、近くに Django の本を見つけました。
昔友人から勧められて、ちょっといじったけど、挫折し、その後ずっと気になっていました。
せっかく教えてもらったのだし、活用しなくてはと思い、本を購入。
この Web ページを Django で作り直そうと計画したが、そもそも契約しているサーバーがこういうものをインストール出来るのかどうか不明であることに後から気が付いた!

このサイトさんによると、
さくらインターネット(スタンダードプラン)は他のユーザとの共有サーバのためデーモンは禁止されており、runserverで立てたDjangoのプロセスは、ターミナルを閉じるとkillされてしまう。
ということだ。サイトさんではそこをなんとか動かすような裏技を紹介してくれているが、動作が重いらしい。

でも、こちらのサイトさんによると、さくら VPS なら Django アプリを公開できるらしいので、そっちに契約を変更すれば良さそうだ。月額もあまり変わらないし…でも契約更新したばかりだから。

この本には、作成した Django アプリを GitHub で公開する手順を紹介しているので、まずはそこからやれば良いかな。
3.8 未読
2022/6/19 ダイソーでマネキンヘッドを買いました。600 円(税別)。
360 度、どの方向からも人間の顔を観察し、イラストのデッサンに役立てるためです。

「3Dのデッサン人形アプリ」を使えば、同じことが自由自在にできて楽しいんですが、昔ながらのレトロアナログな方法のほうが、絵描きの楽しさをもっと十分に享受できると思います。

それはなぜなのかというと、3Dだと、自分の力じゃない誰でもできるという感じがするし、本物のマネキンなら自分の力で描くし、マネキンと自分との間に空気があり存在感があります。難しい話ですが焦点距離(焦点距離小:ペットの鼻デカ画像、焦点距離大:望遠カメラ)もソフトウェアによるものではなく、肉眼の中にある水晶体レンズの焦点距離となるので、見た目らしい描画を望める。そして現実の陰影もついています。3Dほど自由自在さはないけど、限られた条件(このマネキンが提供できるものの限り、女性タイプで細身のみとか)の中でいかに良いものを作り出すか、また、「限られた条件」というのはクリエイターの想像力をあふれさせる力がある(過去の性能の限られたファミコンとか)

だから木でできた昔ながらの「デッサン人形」も良いものだと思っています。
不明 現在
未使用


自己紹介: 自己紹介

47才、男、B型(BB)

電子機器の基板を製造する工場で、派遣で働いています。

プログラミングが好きで小学校5年生のころからずっと続けています。

ページ上にていろいろ才能(少々 粗削りな才能)を発揮していると思いますが、なるべく自 分だけで終わらないようにといつも思っています。

いろいろ厳しい考え方も持っていますが、厳しすぎないように周囲の人々とのバランスも考えていま す。

たとえば、著作権について私はだいぶ細かく考えていますが、私以外の人について 特に厳しく言ったり批判的に見たりはしません。

著作権は難しいし、ちょっとぐらい いいじゃないか、という人間らしい気持ちを肯定したいからです。

■趣味: プログラミング、ゲーム音楽を集めて聴く、イラストを描く、映画、アニメ、ガンプラ (興味の強い順)

■将来の夢は5つくらい持っていますが、生きてる間に実現できそうにありません。


■私が使っているペンネーム(ハンドルネーム)は新しい順に

ペ ンネーム(ハンドルネーム) いつごろ 場 所
sankakkei、三角形(下のペンネームからの交代) NEW 現在(少) Yahoo Japan
daikei、台形(本名の姓の頭文字がK、名がダイ~なので、ダイケイ) 現在(少) Yahoo Japan
d_kawakawa 現在(多) どこでも
cookiepurinman、cookiepudingman ちょっと前 Twitter
かわ、kawa 30年前 パソコン通信

※基本的には d_kawakawa とお呼びください。


■勝手に Q&A

Q: サイトがゴチャゴチャしていて何が何だか。

A: 私が作る作品には「計画性」がなく、「思い付き」で後から次から次へと追加していくような作り方をしています。

そのため、わけわからない感じになっちゃってるかもしれません。

Q: サイト内の一部の表示が、壊れているみたいです。

A: 2021年9月に旧システムから新システムへ移行しました。

そのせいで、旧システムで使っていた機能の互換性が取れていません。

順次対応していますが、時間があまりないのでなかなか直しきれません。

Q: 昔進めていたコンテンツは、途中のままで、終わっているんですか?

下図のように昔進めていたいろいろなコンテンツがありますが、

これら全部「保留」のつもりでいます。

なんか、いろいろ必要なことが別にあって、それぞれ「待ち行列」みたいに並んでいます。

たとえば、今やっている「RPGのメニュー」は、上図の「SVC」と関係があって、つまり、RPGの基本の部分にはメニューがあり、そのメニューを先にクリアしないと「SVC」を作る意味がない気がするんです。

DRAM については1つ難問があって、回路自体はそんなに問題じゃない気がしますが、回路を人々に教えようとするとき、どのマイコンを使うのかが問題で、誰でも手に入り、誰でも実験でき…と考えると、どのマイコンを採用すべきか。また、実験するために安価なオシロスコープはどれだろう、なんて探し始めて、その辺で止まっています。

Q: RPG を作ろうとしているようですが、素人の域を越えられますか?(メジャーになれますか)

素人の域でゴネゴネやっている感じがしていて、果たして上に上がれるのかどうか。

そんなことを言っている私は、つまり上に上がろうとしているってことですね。

RPG のルーツを探ったり、古い RPG の面白さのエッセンスを探し出したりと、「真髄」、「要点」、を研究したり、「実体験をした人にしか出せない言葉がある」とか、INTKSBFS といった 面白い RPG のための「くしざし(頭文字を並べたもの)」も作ったりしているので、たぶん人の心に届く RPG を作る下地はあるんじゃないかと思います。

「大作を作ろうとする人は失敗する」という仮定があって、「実体験をもとに、できる範囲で、規模の小さめの RPG を作る」という方針が、素人の域を超えられるかどうかの一つのカギだと思っています。「小中高校生のため、その両親とのあいだや、友達同士をつなげるような思い出になるようなもの」という利己的ではない利他的なスタイルが絶対に必要だ、という考え方も、そのカギの一つです。

越えられませんと言っているようじゃ、越えられませんので、越えられますとはっきりと言っておきましょう。それだけの年数と研究、倫理観(開発者の気持ちはこうあるべきだ等)を重ねていますから。

でも人間の1つの幸せとして、たった一人の幼い子供さんを、私の作品で楽しませることさえできれば、それで良いんじゃないかという考え方も持っています。そういう意味では超える気がありません(越えられません)ということになるのかな。

どっちなんだよ。青く塗った部分が良いなと思います。

素人の域を越えてメジャーになったって、消費者たちから文句の応酬を食らっているのであれば(アマゾンの有名ゲームタイトルの言われようと来たら)、それは幸せなんでしょうか。


■私への連絡手段:

ごくまれにしかツイートしませんが、私の twitter アカウントはこちらです。

https://twitter.com/cookiepudingman

何かメッセージをくれれば、返事すると思います。

返事がないときはメッセージに気付いていないんだと思います。そのときはすみません。


<<重要>>

それから 2020 年の年末ごろに携帯電話を紛失した関係で、知り合いの電話番号がすべてわからなくなりました。

その後 携帯電話は見つかりましたが、電話帳データを新しい携帯電話へ移動することが、ちょっと面倒で電話帳の復帰をしていません。

なおかつ、最近の詐欺電話の対策として、番号非通知や「電話帳に載っていない電話番号」からの着信には基本的に出ないことにしています。

なので、「知り合いからの着信に出ない」という結果になっていると思います。

「電話帳データ復帰せんかーい!!」って話ですが、とにかく面倒は苦手すぎな性格なので、まぁ運が良ければまた。って感じ。

すまん。べつに嫌いってわけじゃなくて、なんとかなるだろうって思ってるだけです。


■管理人用:

Windows ケア 手順

タッチイベント チェック用



特設ページ群:

PC-9801 臨時特設ページを開く    …特設ページ作りましたが、更新は止まっています。

「夢幻の心臓II」特設ページを開く …また3日坊主になるかも。

電子機器組立て2級 暗記ツール …国家検定の電子機器組立て2級の暗記ツール(基板上配置)です。1級でも役立つと思います。


このサイトで最も興味を引く部分: (そのつもり)

最近、私は個人的に、「RPG のコマンドメニュー部分のプログラム」を、中高生向けに、ステップバイステップ方式で教えようとしています。

ステップ同士のプログラム上の変化をマーキングして表示したり、バルーンメッセージを使って説明を付けたりと、いろいろ工夫をしていますが、はっきりいってわかりにくいんじゃないかと思っています。

Mini-NAVIGATION
RPGメニューを作る1
基本のプログラムからはじめて、サブメニューを表示するまで
Step 1~8
RPGメニューを作る2(記事としては4)
メニューの項目に、付加情報(装備中のe記号や、店の価格)を表示。
Step 9、10、11
RPGメニューを作る3(記事としては5)
メニューの項目を段組表示する
Step 12、13


日記: 日記  (日記がこのサイトのメインコンテンツです。上の記事ほど新しい記事です)

2022/8/31(水)

PC-9801用 Windows 3.1 その2

2022/8/26(金)に Yahoo オークションで私が入札した、Windows 3.1 ですが、見事競り落とせました。

おめでとう。落札価格は 1 万円でした。(Windows 3.1 発売当時の定価はだいたい 2 万円だったそうです)

でもまた、入札者私一人だったので、誰とも競っていません。

Windows 3.1 っていつ頃登場したんだっけ…

Wikipedia によると、1991 年。

今から 31 年前ですねぇ。

31 年前のフロッピーディスク…大丈夫かな。


Windows 3.1 を買う理由は、「はじめて読む486(リンクは Amazon 当該ページ)の一部のテストプログラムが、Windows 3.1 用だからです。

それを試すためには、買う必要があると。それだけ。

そして、Windows 3.1 をどこにインストールするのかというと、おもに 「Neko Project」という PC-9801 エミュレーター上にインストールしようと考えています。


2022/8/28(日)

Excel 図形 → JavaScript 変換 その6

Excel の図形を VBA を使って、.js テキストファイルへ書き出して、JavaScript でその図形を表示する…、というようなことに取り組んでいます。。

前回記事で書いたように、一部の図形(楕円など)はそのままでは 3D 計算できない情報で構成されているので、その情報をベジェ曲線データへ変換する必要があります。

で、実際にベジェ曲線を 3D 回転させようというとき、「配列」などどんなデータ形式なら、扱いやすいのか確認するために、JavaScript での 3D 回転のサンプルを作りました。

前々からこの手の 3D 回転はやってきましたが、改めて、ということで…

There is no canvas.

こういう画面を見ると、ある人は、「WebGL を使ってるのかな」と思うだろうし、ある人は「難しそうだ」と思うでしょう。

でもこれは WebGL のような難しいものは使っていないし、また、3D 計算ではあるけど、3D 計算というのはもともと「難しい数学が不要」で、四則演算と、ちょっとの sin, cos ができれば、できるものなんです。

上の 3D の回転は、下のプログラムでできていますが、ざっとみても、Three.js などの 3D のライブラリにはアクセスしていないし、行列計算も行っていません。


立方体とネコを 3D 回転するプログラム:
test2[20180202-obj/Microsoft Excel]

class App {

constructor( canvas ) {

this.cc = canvas.getContext( "2d" );

this.cc.canvas.width = 512;

this.cc.canvas.height = 448;

this.timerId = null;

this.objectz = {

//====================cube

cube : { //unit: mm

type : 0, //normal

name : "cube",

close : true, //各面は最後に cc.closePath() を行うか

ccPropz : {

fillStyle : "rgba(250,250,100,0.5)",

strokeStyle : "black",

lineWidth : 1,

lineJoin : "round",

},

tens : [

{ x : -1, y : +1, z : -1 }, //0: 左上 手前

{ x : +1, y : +1, z : -1 }, //1: 右上 手前

{ x : +1, y : -1, z : -1 }, //2: 右下 手前

{ x : -1, y : -1, z : -1 }, //3: 左下 手前


{ x : -1, y : +1, z : +1 }, //4: 左上 奥

{ x : +1, y : +1, z : +1 }, //5: 右上 奥

{ x : +1, y : -1, z : +1 }, //6: 右下 奥

{ x : -1, y : -1, z : +1 }, //7: 左下 奥

],

center : { x : 0, y : 0, z : 0 }, //tensが示すモデルの、中心座標


mens : [

[ 0, 1, 2, 3 ], //正面

[ 0, 4, 5, 1 ], //天面

[ 0, 3, 7, 4 ], //左面

[ 2, 6, 7, 3 ], //下面

[ 4, 7, 6, 5 ], //背面

[ 1, 5, 6, 2 ], //右面

],


size : 700,

pos : { x : -800, y : 0, z : 6000 },

rotation : { x : 0, y : 0, z : 0 },

},


//====================cat

bezier : {

type : 1, //bezier

name : "neko",

close : true, //各面は最後に cc.closePath() を行うか

ccPropz : {

fillStyle : "pink",

strokeStyle : "rgb(200,50,150)",

lineWidth : 4,

lineJoin : "round",

},

tens : [


{ x : 478, y : 165, z : 0 }, //1


{ x : 506, y : 162, z : 0 }, //2

{ x : 535, y : 162, z : 0 }, //3

{ x : 563, y : 165, z : 0 }, //4


{ x : 573, y : 147, z : 0 }, //5

{ x : 578, y : 129, z : 0 }, //6

{ x : 592, y : 111, z : 0 }, //7


{ x : 664, y : 206, z : 0 }, //8

{ x : 666, y : 339, z : 0 }, //9

{ x : 521, y : 340, z : 0 }, //10


{ x : 381, y : 339, z : 0 }, //11

{ x : 380, y : 206, z : 0 }, //12

{ x : 450, y : 111, z : 0 }, //13


{ x : 464, y : 130, z : 0 }, //14

{ x : 469, y : 147, z : 0 }, //15

{ x : 478, y : 165, z : 0 }, //16

],

center : { x : 478, y : 230, z : 0 }, //tensが示すモデルの、中心座標


mens : [

[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ],

],

size : 6,

pos : { x : 800, y : 0, z : 6000 },

rotation : { x : 0, y : 0, z : 0 },

},

//====================

}//objects{}


//カメラ

this.cam = {

s : 50, //焦点距離(何mmレンズ)

zoom : 14, //引き伸ばし

}

}//constructor()

start() {

//動作を開始する

//check. すでに動作中

if( this.timerId ) return;

this.tmBak = 0;

this.frame( 0 );

}

stop() {

//動作を停止する

//check. すでに停止中

if( this.timerId == null ) return;

cancelAnimationFrame( this.timerId );

this.timerId = null;

}

frame( tm ) {

if( tm - this.tmBak >= 100 ) { //ミリ秒ごとに

this.tmBak = tm;


//各オブジェクトを回転

let add = 0.01;

for( let name in this.objectz ) {

let object = this.objectz[ name ];

object.rotation.x += add;

object.rotation.y += add;

object.rotation.z += add;

}


this.draw( this.cc );

}

this.timerId = requestAnimationFrame( this.frame.bind( this ) );

}

draw( cc ) {

cc.clearRect( 0, 0, this.cc.canvas.width, this.cc.canvas.height );


cc.save();

cc.translate( this.cc.canvas.width / 2, this.cc.canvas.height / 2 );

cc.scale( 1, -1 );


//各オブジェクトについて

for( let name in this.objectz ) {

let object = this.objectz[ name ];

for( let propName in object.ccPropz ) {

cc[ propName ] = object.ccPropz[ propName ];

}

let bezierPs = new Array();

//1オブジェクトを構成する各面について

for( let i = 0; i < object.mens.length; i++ ) {

let men = object.mens[ i ];

cc.beginPath();

//1面を構成する各点について

for( let j = 0; j < men.length; j++ ) {

let tenIdx = men[ j ];

let ten = object.tens[ tenIdx ];


//ローカル座標

let x = ( ten.x - object.center.x ) * object.size;

let y = ( ten.y - object.center.y ) * object.size;

let z = ( ten.z - object.center.z ) * object.size;


//x, y, z軸回転(自転)

if( object.rotation.x ) {

let res = this.rotate( z, y, object.rotation.x );

z = res.x;

y = res.y;

}

if( object.rotation.y ) {

let res = this.rotate( x, z, object.rotation.y );

x = res.x;

z = res.y;

}

if( object.rotation.z ) {

let res = this.rotate( x, y, object.rotation.z );

x = res.x;

y = res.y;

}


//ワールド座標へ移動

x += object.pos.x;

y += object.pos.y;

z += object.pos.z;


//3D -> 2D

let h = x * ( this.cam.s / z ) * this.cam.zoom;

let v = y * ( this.cam.s / z ) * this.cam.zoom;


//描画

if( j == 0 ) {

cc.moveTo( h, v ); //最初

} else {

//2回目以降

if( object.type == 0 ) {

//cube

cc.lineTo( h, v );

} else {

//bezier

bezierPs.push( h, v );

//check. bezierCurveTo() の引数がそろった

if( bezierPs.length == 6 ) {

cc.bezierCurveTo( ...bezierPs );

bezierPs.length = 0;

}

}

}

}//for j 各点


if( object.close ) cc.closePath();

cc.fill();

cc.stroke();


}//for i 各面

}//for name 各オブジェクト

cc.restore();

}//draw()


//数学 回転計算

rotate( x, y, theta2 ) {

let theta1 = Math.atan2( y, x );

let hankei = Math.sqrt( x * x + y * y );

return {

x : Math.cos( theta1 + theta2 ) * hankei,

y : Math.sin( theta1 + theta2 ) * hankei,

}

}//rotate()

}//App


データの部分を見てしまうと難しそうに見えるかもしれませんが、このプログラムの 3D としての中心的な計算は、181行と、182行の

//3D -> 2D
let h = x * ( this.cam.s / z ) * this.cam.zoom;
let v = y * ( this.cam.s / z ) * this.cam.zoom;

この計算です。

3D 計算というのは、このように実は四則演算だけで描画されています。


で、肝心のベジェ曲線のデータ形式ですが、他の 3D のオブジェクトと同じように、tens という配列の中にベジェのデータを入れるのが良いかなと思います。



2022/8/27(土)

Excel 図形 → JavaScript 変換 その5

私は最近、Excel 上の図形を JavaScript で表示することを考えています。

Excel 上の図形のデータを取り出して、JavaScript で読めるテキストファイルにおさめるだけなら、まだ簡単でしたが、Excel は楕円などの図形を、長半径と短半径、楕円の座標、というようなおおざっぱな情報で表現しているので、JavaScript で 3D 回転などを行いたい場合は、ベジェ曲線に変換しなければなりません。

そこで、今日は、「楕円」を「ベジェ曲線」に変換するプログラムのお話をします。


▼「楕円」を「ベジェ曲線」に変換

▼ベジェ曲線とはハンドルを動かして形を自由に変えられる図形です。 ▼図形を 3D 回転させる
 


楕円→ベジェ変換プログラムの動きを試す

変換プログラムは大変だったんですが、何とかできました。

JavaScript で楕円を描く際の標準のメソッドであるellipse() の描画(オレンジ太線)と、私の自作のベジェ曲線による楕円の描画(青い細線)が一致している様子を下のフォームをいじって確認できます。

There is no canvas.


startAngle:

endAngle:

Script:
Evaluate:


標準の cc.ellipse() の場合の記述と、ベジェの場合の記述

通常、JavaScript で楕円を描画するときは、以下のようにします。

cc.beginPath();
cc.ellipse( 0, 0, a, b, 0, startAngle, endAngle, isReverse );
cc.stroke();

この標準の記述となるべく同じ記述になるように(わかりやすくするために)、プログラムを工夫しました。

以下は、今回作成した変換プログラム(関数)を利用している様子です。

let array = ellipse2bezierPoints( 0, 0, a, b, startAngle, endAngle, isReverse );

cc.beginPath();
drawBezierPoints( cc, array );
cc.stroke();

この、ellipse2bezierPoints() が楕円情報をベジェデータに変換する関数で、drawBezierPoints() がそのベジェデータを画面に描画する関数です。

この2つの関数を少し詳しく紹介します。


自作 JavaScript 関数 ellipse2bezierPoints()

ellipse2bezierPoints() は、標準の cc.ellipse() と同じような引数を取りますが、楕円は描画せずに、「ベジェ曲線のデータ」を作成して返します。

やや長めの関数になっており、行っている処理は、少し複雑になっています。


ellipse2bezierPoints() 関数の流れ:

  1. 楕円をベジェ曲線で描くときは、数学のグラフを座標軸で4分割したときの「象限」単位で描かれる。
    (前回紹介したこのサイトさんの情報をもとに楕円のベジェ曲線を作ると、4半円が描かれました)
    そのため、楕円をベジェ曲線に変換する際は、象限ごとにベジェ曲線を作成する。
    なので、まずは for 文で角度を楕円の開始角度から終了角度まで 0.1 ずつ進めて、4つの象限をどの順番でたどるのかを検出する。
    (…という方法を私は取りましたが、もっと良い方法が世間にはあると思います)
  2. とりあえず、その1つの象限で描画される楕円の一部(4半円)を描くベジェ曲線を得る。
    (下記プログラムリスト 76 行目、let currentBezier = ellipseBeziers[ shogen ]; でそれを行っています)

  3. ある変数 t を 0 から 1 まで 0.01 ずつ進めると、1つのベジェ曲線を形作る約 100 個(99個かな?)の点を得られるという考え方でプログラムする。
    (下図は変数 t を 0 から 1 まで 0.25 ずつ進めて、3個の点を得ている例です)

    その1つ1つの点を算出するときに使用する「過程の点」と、その算出結果である「結果の点」を得る。
    (下記プログラムリスト 870 行目、let bo = getBezierObject( t, currentBezier ); でそれを行っています)

  4. 『その「結果の点」を Math.atan2() の引数に入れて得られる角度が、描こうとする楕円の開始角度と終了角度の範囲内であるかどうか』を判定する。
    (この判定がえらく難しかった。プログラムの 41 ~ 53 行の diffAngle を求めるところ。判定自体は 100 行目です)

    その判定によって、「4半円のベジェを2つのベジェへ分割する」かどうかが変わる。
    1つのベジェを2つのベジェへ分割するには、「過程の点」を使う。
    (分割について詳しくは前回も参照したこちらのサイトさんを参照してください)
  5. 4象限分のベジェを作成したら、最後にその各ベジェを、1つの「ベジェ曲線のデータ」として結合して return して、終了。


ellipse2bezierPoints() は以上のような流れで、楕円をベジェデータに変換しています。

実際のプログラムは下記です。

上記1~5の説明の出だしをプログラムの中のコメントで書いてあるので、上記流れの説明との対応関係がわかると思います。


楕円→ベジェデータ変換の ellipse2bezierPoints()  のプログラムリスト:

test2[20180202-obj/Microsoft Excel]
function ellipse2bezierPoints( x, y, radiusX, radiusY, startAngle, endAngle, isReverse ) {



//======================================================

//1.楕円をベジェ曲線で描くときは、数学のグラフを座標軸で4分割したときの「象限」単位で描かれる。…


let ellipseBeziers = [

[ //右下の象限の最初のベジェ(完全な4半円)

{ x : radiusX, y : 0 },

{ x : radiusX, y : .552 * radiusY },

{ x : .552 * radiusX, y : radiusY },

{ x : 0, y : radiusY },

],

[ //左下の象限の最初のベジェ(完全な4半円)

{ x : 0, y : radiusY },

{ x : -.552 * radiusX, y : radiusY },

{ x : -radiusX, y : .552 * radiusY },

{ x : -radiusX, y : 0 },

],

[ //左上の象限の最初のベジェ(完全な4半円)

{ x : -radiusX, y : 0 },

{ x : -radiusX, y : -.552 * radiusY },

{ x : -.552 * radiusX, y : -radiusY },

{ x : 0, y : -radiusY },

],

[ //右上の象限の最初のベジェ(完全な4半円)

{ x : 0, y : -radiusY },

{ x : .552 * radiusX, y : -radiusY },

{ x : radiusX, y : -.552 * radiusY },

{ x : radiusX, y : 0 },

],

];



let beziers = new Array();


let adjust = isReverse ? norm( endAngle ) : norm( startAngle );

let shogenBak = -1;

let shogenCount = 0;

let tail;


//下記 //◆ で示す部分の for のパラメーター

let diffAngle;

let pi360 = Math.PI * 2;

if( endAngle > startAngle ) {

diffAngle = endAngle - startAngle;

if( isReverse ) diffAngle = pi360 - diffAngle % pi360;

} else if( startAngle > endAngle ) {

diffAngle = startAngle - endAngle;

if( ! isReverse ) diffAngle = pi360 - diffAngle % pi360;

} else {

//startAngle == endAngle

diffAngle = 0;

}


let iStep = 0.1;

let aStep = isReverse ? -iStep : iStep;


//◆ 角度 a は四半円分移動する。(この角度 a は象限を検出するためにだけ利用している)

for( let i = 0, a = startAngle; i < diffAngle; i += iStep, a += aStep ) {

let shogen = Math.floor( norm( a ) / ( Math.PI / 2 ) ) % 4;

//check.

if( shogen == shogenBak ) continue;


//ここで新しい象限が検出された



//======================================================

//2.とりあえず、その1つの象限で描画される楕円の一部(4半円)を描くベジェ曲線を得る。…


let isSuddenly = false; //その象限に入った時点ですでに対象範囲内だったというフラグ

let changeCount = 0; //その象限内で、対象範囲の開始・終了が切り替わった回数

let areaNow = false; //現在対象範囲であるというフラグ


let quarterBeziers = new Array(); //象限内に作成されたベジェ(個数は0個、1個、2個のいずれかで3個には決してならない)

let currentBezier = ellipseBeziers[ shogen ]; //現在加工中のベジェ


//tweak. 反時計回りの時は、ベジェパラメーターを逆並びにする。

if( isReverse ) currentBezier = currentBezier.reverse();



//======================================================

//3.ある変数 t を 0 から 1 まで 0.01 ずつ進めると、1つのベジェ曲線を形作る約 100 個…


//その象限についてtを0から1まで変化させる。楕円の曲線を形作る点 p が得られる。(※currentBezierそのものから点pは得られない)

for( let t = 0; t < 1; t += 0.01 ) {

let bo = getBezierObject( t, currentBezier );

//boのメンバ

//bo.result t に対応する、ベジェ曲線上の点

//bo.roots bo.result を算出する際にできる、bo.result を頂点としたツリーの左側面と右側面

//bo.pointsByT bo.result を算出する際に使用する一時的なもの



//======================================================

//4.その「結果の点」を Math.atan2() の引数に入れて得られる角度は、描こうとする楕円の開始角度と…


let p = bo.result;


//その点の角度を得る

let rate = radiusX / radiusY;


let angle = norm( Math.atan2( p.y * rate, p.x ) - adjust ); // % ( Math.PI * 2 );

if( angle >= 0 && angle <= diffAngle ) {

if( ! areaNow ) {

//対象範囲に入った


//check. 初回の象限であり、その象限の最初である。(いきなり始まった分は末尾の端かもしれない)

if( shogenCount == 0 && t == 0 ) isSuddenly = true;


changeCount ++;

areaNow = true;


//check.

if( t == 0 ) continue; //初回はベジェ分割しない


//ベジェを分割

currentBezier = bo.roots[ 1 ]; //前ベジェは範囲外なので破棄し、後ベジェをカレントにする。

t = 0;

}

} else {

if( areaNow ) {

//対象範囲から出た

changeCount ++;

areaNow = false;


//ベジェを分割

quarterBeziers.push( bo.roots[ 0 ] );

currentBezier = bo.roots[ 1 ];

t = 0;

}

}

}//for t


//この時点で1つの象限を見た


//check. エリア内のまま象限を終えた

if( areaNow ) quarterBeziers.push( currentBezier );

//check. いきなり始まった分は末尾の端だった

if( isSuddenly && changeCount >= 2 ) tail = quarterBeziers.shift();


//この象限分のベジェを追加

beziers.push( ...quarterBeziers );


shogenBak = shogen;

shogenCount ++;

//check. 象限は4つ見ればよい

if( shogenCount == 4 ) break;//for i

}//for i, a


//check. 末尾の端

if( tail ) beziers.push( tail );


//ここで beziers は得られた。



//======================================================

//5.4象限分のベジェを作成したら、最後にその各ベジェを、1つの「ベジェ曲線のデータ」として…


//beziers を1つのベジェへ結合する

let bezierPoints = new Array();

let before;

for( let i = 0; i < beziers.length; i++ ) {

let bezier = beziers[ i ];

for( let j = 0; j < bezier.length; j++ ) {

let p = bezier[ j ];

//check. 同じ点はスキップ

if( i > 0 && p.x == before.x && p.y == before.y ) continue;

bezierPoints.push( p );

before = p;

}

}//for i


return bezierPoints;


}//ellipse2bezierPoints()


//角度から、余分な回転を削除し、角度が負の場合は正に直す。

function norm( angle ) {

angle = angle % ( Math.PI * 2 );

if( angle < 0 ) angle += Math.PI * 2;

return angle;

}


//ベジェの原理の「過程と結果」オブジェクトを得る

function getBezierObject( t, bo ) {

//check. 最初は bo は配列が渡される。

if( bo instanceof Array ) {

bo = { pointsByT : bo, roots : [ [], [] ] };

}


//check. 「ベジェの分割」時のための情報記録

bo.roots[ 0 ].push( bo.pointsByT[ 0 ] ); //"木構造のうち一番外側の点"(片側)

bo.roots[ 1 ].push( bo.pointsByT[ bo.pointsByT.length - 1 ] ); //"木構造のうち一番外側の点"(片側)


let newPointsByT = new Array();

for( let i = 0; i < bo.pointsByT.length - 1; i++ ) {

let sp = bo.pointsByT[ i ];

let ep = bo.pointsByT[ i + 1 ];

let lenX = ep.x - sp.x;

let lenY = ep.y - sp.y;

newPointsByT.push( {

x : lenX * t + sp.x,

y : lenY * t + sp.y

} );

}


bo.pointsByT = newPointsByT;


//再帰終了

if( bo.pointsByT.length == 1 ) {

//check. 「ベジェの分割」時のための情報記録

bo.roots[ 0 ].push( bo.pointsByT[ 0 ] );

bo.roots[ 1 ].push( bo.pointsByT[ 0 ] );


//check.

//そのままだと両側から1点に向かう2つのベジェとなっているので、

//片方のベジェ([1])は点から端に向かうベジェに直す

bo.roots[ 1 ] = bo.roots[ 1 ].reverse();


bo.result = bo.pointsByT[ 0 ];

return bo;

} else

return getBezierObject( t, bo );

}//getBezierObject()




自作 JavaScript 関数 drawBezierPoints()

変換で作成された「ベジェ曲線のデータ」をもとに、cc.beziercurveTo() メソッドを使ってベジェ曲線を描画します。

「ベジェ曲線のデータ」は1次元配列ですが、最初に描画開始の点、その次から cc.bezierCurveTo() に渡す3つの点が cc.bezierCurveTo() の回数分繰り返される、というようなフォーマットになっています。

描画開始の
点の x, y 座標
cc.bezierCurveTo() に
渡す点1の x, y 座標
cc.bezierCurveTo() に
渡す点2の x, y 座標
cc.bezierCurveTo() に
渡す点3の x, y 座標
cc.bezierCurveTo() に
渡す点1の x, y 座標
cc.bezierCurveTo() に
渡す点2の x, y 座標
cc.bezierCurveTo() に
渡す点3の x, y 座標
cc.bezierCurveTo() に
渡す点1の x, y 座標
cc.bezierCurveTo() に
渡す点2の x, y 座標
cc.bezierCurveTo() に
渡す点3の x, y 座標
cc.bezierCurveTo() に
渡す点1の x, y 座標
・ ・ ・ つづく


ベジェデータ描画の drawBezierPoints() のプログラムリスト:

test2[20180202-obj/Microsoft Excel]

function drawBezierPoints( cc, bezierPoints ) {

//check.

if( bezierPoints.length == 0 ) return;

cc.moveTo( bezierPoints[ 0 ].x, bezierPoints[ 0 ].y );

for( let i = 1; i < bezierPoints.length; i += 3 ) {

let p1 = bezierPoints[ i ];

let p2 = bezierPoints[ i + 1 ];

let p3 = bezierPoints[ i + 2 ];

cc.bezierCurveTo( p1.x, p1.y, p2.x, p2.y, p3.x, p3.y );

}

}//drawBezierPoints()


この関数はベジェのデータ・フォーマットの通りに点1~3を取り出して、bezierCurveTo() を行う内容になっています。

cc.bezierCurveTo() は下図のようなメソッドです。

この bezierCurveTo() に渡す各点を、事前に 3D 計算してから bezierCurveTo() に渡してやると、ベジェ曲線が 3D 空間に描かれます。


2022/8/26(金)

PC-9801用 Windows 3.1 その1

このヤフオクの入札1件、私ですねぇ。


2022/8/15(月)

Excel 図形 → JavaScript 変換 その4

前回からのつづきで、

>だからこのあと、楕円をベジェのハンドルで表現する作業(楕円→ベジェの変換)をやらなければなりません。

ということで、「楕円をベジェ曲線に変換する」というのを現在行っています。


下図は、

赤い点が、「楕円を描く式」で描いた楕円。

緑の太い線が、「JavaScript のビルトイン関数(最初から用意されている関数)」で描いた楕円の一部。

そして、オレンジ色の細い線が「ベジェの計算」で描いた同じ楕円の一部です。

ちゃんとベジェで描くことが出来ましたが、結構大変でした


必要だった計算は、

  1. ベジェ曲線の計算のしかた(結局は使わない結果になりましたが、大変参考になりました) 参考サイトさん
    このサイトさんの最初のほうに載っている「ベジェ曲線の数式」は難しくて私には全然わからなかったのですが、後のほうの小題「3次のベジェ曲線を数式で」の Swift プログラムをコピペして JavaScript に書き換えました。
    ベジェ曲線を描くことができ、良かったんですが、
    でも、これは「数式を使って、あらかじめ決まったベジェ曲線を描く方法」であり、「任意の角度から始まる楕円の一部」を描きたい場合には不向きなようでした。
    「任意の角度から始まる楕円の一部」を描くことに対応するためには、「楕円の4半円のベジェ」(下記2番で得られるベジェ曲線)を分割する必要があります。任意の角度は、楕円上の1点を指し示し、そこからベジェ曲線を描くことになります。
    その1点でベジェ曲線を分割するためには、その曲線上の1点を得るために使用した、ベジェを描く原理(手順)の点情報が必要になります。
    結局は、下記の3番のサイトさんの、小題「アルゴリズム」(原理)を見ながら、自分で「ベジェ曲線の描画」をプログラムすることになりました。
  2. 楕円をベジェ曲線で描く方法 参考サイトさん
    必要な数式は、このサイトさんの上から1/3付近にありました。
    >長辺側の補助線長さ = 4 / 3 * ( sqrt( 2 ) - 1 ) *短辺長さ
    >短辺側の補助線長さ = 4 / 3 * ( sqrt( 2 ) - 1 ) *長辺長さ

    ということですが、数式の一部は、0.552 ということなので、
    長辺側の補助線長さ = 0.552 *短辺長さ
    短辺側の補助線長さ = 0.552 *長辺長さ
    となりました。どの楕円も、ベジェを描くにはこの計算になる、とは意外ですね。
  3. ベジェ曲線を途中で分割する方法 参考サイトさん
    このサイトさんの小題「再帰を利用した手法」の説明で、1つのベジェ曲線を2つのベジェ曲線へ分割することが出来ました。
    (でもどうしてその方法で分割できるのかは、理由がわかりませんでした)



cygwin、gcc、mingw、そして Clan の関係性 再度修正

先月7/22に、同題名の記事を書きましたが、その中の図がまだ間違っていることに気付いて、今日になって修正をしました。

下図は修正した図です。

詳しくは、同記事へ飛んでください


2022/8/13(土)

Excel 図形 → JavaScript 変換 その3

下図の左が Excel の画面、右がインターネットブラウザの画面です。

Excel VBA により、Excel シート上の図形が .js ファイルへ「ドローデータ」として保存されます。

「ドロー」とは点の位置や、線の長さ、曲線の曲がり具合などを数値として示した画像データのことです。

その .js をデータとして JavaScript で読み取り、データの通りに描画したものが上図の右側というわけです。赤丸急上昇


データがネイティブになっている、という名の難問

Excel で作成できる図形には種類があり、

  1. 複雑な曲線(ベジェ曲線)で作成されるフリーフォームという図形
  2. オートシェイプと呼ばれる図形
  3. オートシェイプの中に特殊な「点」があり、その点を動かすと図形の形状が太くなったり細くなったりと変えられる図形

の3種類が、大まかですが あります。

この 1 番と 2 番は「データとして何ら問題ない」のですが、今非常に困っているのが、3 番の「点を動かすと形が変わる図形」です。


▼黄色い「点」、つまり黄色い「◆」のある図形は、「◆」を動かすとその形を変えられる。


このタイプの図形は、「◆」の位置情報はデータとして読めるのですが、かんじんの「形のデータ」がどこにもないんです。

たとえば、上図の月なら、月を満ち掛けさせる「◆」の位置情報はあるけど、かんじんの月の形のデータがナイ!

星を太らせたりやせさせたりする「◆」の位置情報はあるけど、かんじんの星の形のデータがナイ!


▼これら小さな■で示される、「形のデータ」が VBA 上にナイ~!


それから、すべての図形が持っている「AutoShapeType」というプロパティを、たとえば msoMoonShape という数値から、msoStarShape という数値へ VBA で「変更するだけ」で、月だったものが星へ、一瞬にして切り替わる! AutoShapeType に代入するだけで不思議と変わる!

それで もしかしてと思いました、


つまり(たぶんですが)、

「msoMoonShape なら、それを描く専用の関数があり、その中で月を描いてる」

「msoStarShape ならそれを描く専用の関数があり、その中で星を描いてる」

…となっていて、つまり平たく言うと、形を描くところは「ネイティブになっている」、ということのようです。

(ネイティブ:Excel 内部の機械語の状態でしか存在していない)


ベジェのデータさえあれば良いので、月や星を「フリーフォーム」(ベジェデータだけで構成される)タイプの図形に変換する VBA のメソッドはないかなと思って探したんですが、ありませんでした。

その時点で私のこの「Excel 図形 → JavaScript 変換のプログラム」は、とても困難になってしまう、ということが確定してしまうんです。

”してしまう” じゃなくて、確定しました。


ネイティブになっている描画を自作しよう

それで、今回一番最初の図で示した通り、Excel の「月の満ち欠け」 が JavaScript で再現されているんですが、それはとても大変でした

1. 月の欠けと楕円の大きさの関係を調査 2. 調査の通りの楕円を得る数式を試行錯誤 3. そして、これでいいかなと思った数式。

← 月が欠けるほど、
赤い楕円の縦幅は せまくなる。
またその位置も左へずれていく。

Excel のこの動きをピッタリ再現しなければならない

緑のグラフの「要所」(point)に沿うように、赤のグラフを、数式を変えて近づけていく作業。
表中の adjust は「★」の位置情報 0 ~ 0.875 です。

 JavaScript です。

まぁ、後から気付いたんですが、JavaScript で再現できても、その図形を JavaScript で 3D 回転させたい場合、「◆」の位置をベースにした上記の図形の描き方だと、ダメ(正しく3D回転できない)なんじゃないかなぁと。

だからこのあと、楕円をベジェのハンドルで表現する作業(楕円→ベジェの変換)をやらなければなりません。


「◆」を持った図形は Excel には他にもたくさんありますが、それら1つ1つ調査したりはできないので、「顔の眉毛でよく使っている月図形」のように、実際に絵を描くときに使っている図形に限る必要があります。


2022/8/7(日)

おそなえもの

おそなえものを買ってきました。(左写真)

おそなえものを飾る準備はなかったので、誰かが退職時に私にくれた贈り物の小タオルで飾りました。(右写真)





ご先祖様には子供もいるんじゃないか、と思ってお菓子も付けました。


インターネット不要論

  • ネットいじめ
  • ネットゲーム依存
  • いろいろな犯罪の温床
  • チャットでケンカ
  • 学校の課題を知恵袋にまるごと聞いて、回答者はあいさつもせず解答だけを出して終わり。
  • みんなでテーブルで向かい合って、または電車内で横に並んでスマートホンを見ている。どこがコミュニケーションツール?
  • 不健康
  • 性的なコンテンツでいっぱいなのと、だまされてそれらに出演することになった人。(まぁ最近法律ができてよかったけど)
  • 片方は自分の才能を披露出来て自慢したい気持ちを満たし、片方はそれを見せられて劣等感をいだいて無理に能力を引き出して頑張ったりする。現実でもそれはあるけど、なんというか、それが常に続いていて、平穏じゃない気がする。

だから、私は世界の必要なインターネット(医学的に生命維持がネットの機能とつながっているとか、科学技術研究とか)だけを選択的に残して、不要なインターネットをすべて止めてしまいたいです。

ネットのない1980年代、本屋に行くと まっさきに「コンピューター」の棚に直行して、立ち読みを続けていたあのころが一番良かったと思います。

この人類の歴史の中で、今 これからそれ(インターネットを選択的に止める)が起こっても、特に不思議なことではなく、「人類は英断をしたな、よくそんなことが実現できたな」と後世の人たちは思うのではと思います。

それとも「あのときインターネットを止めなければ…」と悔やむのでしょうか。


上記の1つ1つを良い方向にもっていく具体的なものが見えれば、インターネットも認めても良いと思います。(下から2番目に法律を作ったように)

でも上記のように簡単にリストアップできて、それで効果的な対処もあまりできずに、「使っていたい」っていうのはホントにそれで良いんでしょうか。


2022/8/6(土)

Excel 図形 → JavaScript 変換 その2

前の記事に引き続いて、Excel 図形の JavaScript への変換のお話です。

グループ化された図形と、複雑なベジェ曲線の図形に対応しました。

まだ、いろいろ対応しなきゃいけない図形があります。

グラデーションとかも絵を描くとき、ときどき使うから、それも対応しなきゃならないです。


2022/8/3(水)

Excel 図形 → JavaScript 変換


結構昔から「Excel で作成した図形を、JavaScript のデータへ変換できないか?」と思ってきました。

それで最近、Excel の VBA 言語を使って、取り組み始めました。

今日はやっと下図のように Excel の図形(左)を、JavaScript のデータにして CANVAS で描画(右)できるようになりました。

とりあえず、直線だけの図のみで、曲線ありの図はまだこれからです。

VBA はとにかく「くせ」だらけの環境なので、プログラミングするのが大変です。


(訪問者のどんなニーズと この記事がつながるか)